package net.sashag.nadlandroid;

import java.util.ArrayList;
import java.util.List;

import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.Spinner;
import android.widget.Toast;

import com.google.android.apps.analytics.easytracking.TrackedActivity;
import com.googlecode.androidannotations.annotations.AfterTextChange;
import com.googlecode.androidannotations.annotations.AfterViews;
import com.googlecode.androidannotations.annotations.Background;
import com.googlecode.androidannotations.annotations.Bean;
import com.googlecode.androidannotations.annotations.Click;
import com.googlecode.androidannotations.annotations.EActivity;
import com.googlecode.androidannotations.annotations.InstanceState;
import com.googlecode.androidannotations.annotations.ItemClick;
import com.googlecode.androidannotations.annotations.ItemLongClick;
import com.googlecode.androidannotations.annotations.UiThread;
import com.googlecode.androidannotations.annotations.ViewById;
import com.parse.ParseException;
import com.parse.ParseUser;

@EActivity(R.layout.submitlisting)
public class SubmitListingActivity extends TrackedActivity {

	private static final int PICK_LOCATION_CODE = 611;
	private static final int CAMERA_CAPTURE_REQUEST_CODE = 612;
	
	@ViewById protected Spinner spnBedrooms;
	@ViewById protected EditText edtAddress;
	@ViewById protected EditText edtPrice;
	@ViewById protected CheckBox chkLift;
	@ViewById protected CheckBox chkAC;
	@ViewById protected CheckBox chkParking;
	@ViewById protected EditText edtNotes;
	@ViewById protected EditText edtPhoneNumber;
	@ViewById protected EditText edtEmailAddress;
	@ViewById protected GridView grdPictures;

	@Bean
	protected LocationHelper locationHelper;
	
	private Location lastKnownLocation;
	private ProgressDialog waitDialog;
	private ImageGridAdapter imageAdapter;
	
	@InstanceState protected ArrayList<Bitmap> capturedBitmaps = new ArrayList<Bitmap>();
	
	@AfterViews
	protected void initUi() {
		ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this, android.R.layout.simple_spinner_item,
				new Integer[] { 0, 1, 2, 3, 4, 5, 6, 7 });
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		spnBedrooms.setAdapter(adapter);
		spnBedrooms.setSelection(2);
		
		String phoneNumber = ParseUser.getCurrentUser().getString("Phone");
		if (phoneNumber == null) {
			TelephonyManager telManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
			phoneNumber = telManager.getLine1Number();
		}
		if (phoneNumber != null && phoneNumber.length() > 0) {
			edtPhoneNumber.setText(phoneNumber);
		}
		String emailAddress = ParseUser.getCurrentUser().getEmail();
		if (emailAddress != null && emailAddress.length() > 0) {
			edtEmailAddress.setText(emailAddress);
		}
		
		setupPicturesGrid();
	}
	
	@ItemClick(R.id.grdPictures)
	protected void onPictureClicked(int position) {
		if (position == imageAdapter.getCount() - 1) {
			//Placeholder image clicked, launch camera capture UI
			launchCameraCapture();
		}
	}
	
	@ItemLongClick(R.id.grdPictures)
	protected void onPictureLongClicked(int position) {
		if (position != imageAdapter.getCount() - 1) {
			//One of the captured images clicked, delete it
			capturedBitmaps.remove(position);
			imageAdapter.removeImage(position);
		}
	}
	
	private void setupPicturesGrid() {
		imageAdapter = new ImageGridAdapter(this);
		grdPictures.setAdapter(imageAdapter);
		
		if (capturedBitmaps.size() == 0) {
			Bitmap initialBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.photoapartment);
			capturedBitmaps.add(initialBitmap);
			imageAdapter.addImage(initialBitmap, true);
		} else {
			//We have stored state from before this activity took a configuration change, restore it.
			for (Bitmap bitmap : capturedBitmaps)
				imageAdapter.addImage(bitmap, false /*add in order*/);
		}		
	}
	
	private void launchCameraCapture() {
		Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
		startActivityForResult(cameraIntent, CAMERA_CAPTURE_REQUEST_CODE);
	}
	
	@Click(R.id.btnPickOnMap)
	protected void onPickOnMapClicked() {
		String address = edtAddress.getText().toString();
		Intent launch = new PickLocationActivity_.IntentBuilder_(this).providedAddress(address).get();
		startActivityForResult(launch, PICK_LOCATION_CODE);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (requestCode == PICK_LOCATION_CODE && resultCode == RESULT_OK) {
			edtAddress.setText(data.getStringExtra("Address"));
			lastKnownLocation = data.getParcelableExtra("Location");
		} else if (requestCode == CAMERA_CAPTURE_REQUEST_CODE && resultCode == RESULT_OK) {
			Bitmap photo = (Bitmap) data.getExtras().get("data");
			capturedBitmaps.add(0, photo);
			imageAdapter.addImage(photo, true /*insert first*/);
			//TODO: This is actually just a thumbnail, we need the image itself
		}
	}
	
	@AfterTextChange(R.id.edtAddress)
	protected void onAddressTextChanged() {
		lastKnownLocation = null;
	}
	
	@UiThread
	protected void incrementProgress(int progress, String description) {
		waitDialog.setProgress(waitDialog.getProgress() + progress);
		waitDialog.setMessage(description);
	}
	
	@Background
	protected void submitListing() {
		final Apartment apartment = new Apartment();
		apartment.setAddress(edtAddress.getText().toString());
		apartment.setBedrooms((int)(Integer)spnBedrooms.getSelectedItem());
		apartment.setPrice(Integer.parseInt(edtPrice.getText().toString()));
		apartment.setHasLift(chkLift.isChecked());
		apartment.setHasAC(chkAC.isChecked());
		apartment.setHasParking(chkParking.isChecked());
		apartment.setNotes(edtNotes.getText().toString());
		apartment.setEmail(edtEmailAddress.getText().toString());
		apartment.setPhone(edtPhoneNumber.getText().toString());
		
		final String address = apartment.getAddress();
		incrementProgress(10, "Recording apartment location...");
		if (lastKnownLocation != null) {
			apartment.setLatitude(lastKnownLocation.getLatitude());
			apartment.setLongitude(lastKnownLocation.getLongitude());
		} else {
			Location result = locationHelper.geocodeAddressAndReturnFirstPoint(address);
			if (result == null) {
				submissionFailed("Could not find address: " + address + ", try picking it on the map");
				return;
			} else {
				apartment.setLatitude(result.getLatitude());
				apartment.setLongitude(result.getLongitude());
			}
		}
		
		incrementProgress(10, "Uploading files...");
		final int filesToUpload = capturedBitmaps.size() - 1; //Last one is placeholder
		for (int i = 0; i < filesToUpload; ++i) {
			apartment.addPicture(capturedBitmaps.get(i));
		}
		
		final List<String> channelsToPush = new ArrayList<String>();
		Region[] regions;
		try {
			regions = Region.getAllRegions();
			for (Region region : regions) {
				if (apartment.isWithinRegion(region)) {
					channelsToPush.add(region.getName());
				}
			}
		} catch (ParseException e) {
			Log.w("SubmitListingActivity", "Error retrieving regions: " + e.getMessage());
		}
		
		apartment.saveAsParseObject(new ProgressReporter() {
			public void progress(int completed, int total) {
				incrementProgress(
						(100-20)/filesToUpload,
						String.format("Uploading file %d out of %d", completed, total));
			}
			public void done() {
				if (channelsToPush.size() > 0) {
					NadlandroidPushNewApartment push = new NadlandroidPushNewApartment(apartment.getObjectId(), channelsToPush);
					sendPush(push);
				}
				submissionDone(address);
			}
			public void error(Exception ex) {
				submissionFailed(ex.getMessage());
			}
		});
	}
	
	@Background
	protected void sendPush(NadlandroidPushNewApartment push) {
		push.send();
	}
	
	@UiThread
	protected void submissionFailed(String message) {
		waitDialog.dismiss();
		Toast.makeText(this, message,
				Toast.LENGTH_LONG).show();		
	}
	
	@UiThread
	protected void submissionDone(String address) {
		waitDialog.dismiss();
		Toast.makeText(this,
				"Apartment added successfully, address: " + address,
				Toast.LENGTH_LONG).show();
		finish();
	}
	
	@Click(R.id.btnSubmit)
	protected void onSubmitClicked() {
		String address = edtAddress.getText().toString();
		if (address == null || address.equals("")) {
			Toast.makeText(this, "You must specify an address", Toast.LENGTH_SHORT).show();
			return;
		}
		waitDialog = new ProgressDialog(this);
		waitDialog.setTitle("Please Wait");
		waitDialog.setMessage("Adding your apartment listing...");
		waitDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		waitDialog.setMax(100);
		waitDialog.setProgress(0);
		waitDialog.setCancelable(false);
		waitDialog.show();
		submitListing();
	}
}
